#!/system/bin/sh

# Define the path to the settings file
settings="/data/adb/box/settings.ini"

# Check if 'busybox' is installed; if not, add the necessary paths to the environment PATH variable
if ! command -v busybox &> /dev/null; then
  export PATH="/data/adb/magisk:/data/adb/ksu/bin:/data/adb/ap/bin:$PATH:/system/bin"
fi

# Retrieve the current time in 12-hour format
current_time=$(date +"%I:%M %P")

# Set the port numbers for tproxy and redir functionalities
tproxy_port="9898"
redir_port="9797"

# Enable or disable IPv6 support: true / false
ipv6="false"

# Define a list of available kernel binaries
bin_list=("clash" "sing-box" "xray" "v2fly" "hysteria")

# Specify which option to use for running and downloading premium or mihomo. Ensure premium and mihomo kernels are placed in the /data/adb/box/bin directory
xclash_option="mihomo"

# Select the client to use: clash / sing-box / xray / v2fly / hysteria
bin_name="clash"

# This script is used to set the user and group for BFM core files, if setgiduid is unknown, set it to 0:3005.
box_user_group="root:net_admin"

# Define the network modes:
# redirect: handles tcp + udp[direct]
# tproxy: handles tcp + udp
# mixed: redirect[tcp] + tun[udp]
# enhance: redirect[tcp] + tproxy[udp]
# tun: handles tcp + udp (auto-route)
network_mode="tproxy"

# Configure cgroup to limit memory usage
cgroup_memcg="false"
memcg_limit="100M"

# Configure cgroup for cpuset usage
cgroup_cpuset="false"
# If empty it will be filled in auto
allow_cpu="0-7"

# Configure cgroup for blkio usage
cgroup_blkio="false"
# default 900 if empty
weight=""

# Set box directory variables
box_dir="/data/adb/box"
box_run="${box_dir}/run"
box_log="${box_run}/runs.log"
box_pid="${box_run}/box.pid"
bin_dir="${box_dir}/bin"
bin_path="${bin_dir}/${bin_name}"

# If you don't want to generate the /run/${bin_name}.log file (because it will grow in size over time), replace "${box_run}/${bin_name}.log" with "/dev/null"
bin_log="${box_run}/${bin_name}.log"
# bin_log="/dev/null"

system_packages_file="/data/system/packages.list"
uid_list=("/data/adb/box/run/appuid.list")

# Update subscription & geox. Set update interval using cron, for more information: https://crontab.guru/, set 'true' to enable Cron job
# will update every hour at 00, 06, 12, 18
interva_update="0 0,6,12,18 * * *"
run_crontab="false"

# Type "su -c /data/adb/box/scripts/box.tool geox" to update geox
update_geo="false"

# If "renew=true", it will update $name_clash_config; if false, it will only retrieve proxies: [] for proxy-providers: [].
# Type "su -c /data/adb/box/scripts/box.tool subs" to update subscription
renew="false"
update_subscription="false"

# Source subscription URL for Clash configuration
# if "renew=treu" , will only process the first url"
subscription_url_clash=("http://127.0.0.1:12345/api/file/clash1.yaml" "http://127.0.0.1:12345/api/file/clash2.yaml")

# Source subscription URL for sing-box configuration
subscription_url_singbox="http://127.0.0.1:12345/api/file/sing.json"

# Clash configuration
name_clash_config="config.yaml"
clash_config="${box_dir}/clash/${name_clash_config}"

# Clash subscription
name_provide_clash_config=("subscription.yaml" "subscription2.yaml")
clash_provide_path="${box_dir}/clash/subscription"

# Support rules specified in subscriptions. This is useful when the subscription contains customized rules as well.
# It will fetch rules: [] from the $subscription_url_clash configuration and add them to $name_clash_config; this has no effect if renew=true.
custom_rules_subs="false"
name_provide_clash_rules="rules.yaml"
clash_provide_rules="${box_dir}/clash/subscription/${name_provide_clash_rules}"

# Sing configuration
name_sing_config="config.json"
sing_config="${box_dir}/sing-box/${name_sing_config}"

# Xray configuration
name_xray_config="config.json"
xray_config="${box_dir}/xray/${name_xray_config}"

# V2ray configuration
name_v2fly_config="config.json"
v2fly_config="${box_dir}/v2fly/${name_v2fly_config}"

# Hysteria configuration
name_hysteria_config="config.yaml"
hysteria_config="${box_dir}/hysteria/${name_hysteria_config}"

write_listap=$(dirname "$settings")/ap.list.cfg
# Check pkg config file
[ -d ${write_listap} ] && rm -rf ${write_listap}
[ ! -f ${write_listap} ] && cat > ${write_listap}<<init
# Allow access for network interfaces with the following prefixes: ap+, wlan+, rndis+, swlan+, ncm+, and eth+
# allow <interface name>
allow ap+
allow wlan+
allow rndis+
allow swlan+
allow ncm+
allow eth+
# -----------------🌼🌼----------------------- #
# Ignore specific network interfaces that may conflict with the allowed list
# ignore <interface name>
# ignore swlan+
# ignore wlan+
init

# Read the list of allowed network interfaces from the configuration file "ap.list.cfg"
ap_list=($(busybox awk '/^allow / {print $2}' ${write_listap}))
# Read the list of ignored network interfaces from the configuration file "ap.list.cfg". These interfaces will be excluded from the output, not applicable in fake-ip mode.
ignore_out_list=($(busybox awk '/^ignore / {print $2}' ${write_listap}))

# Define the package.list.cfg path
pkg_config=$(dirname "$settings")/package.list.cfg
# Check pkg config file
[ -d ${pkg_config} ] && rm -rf ${pkg_config}
[ ! -f ${pkg_config} ] && cat > ${pkg_config}<<init
# black/white list mode.
mode:blacklist
# +----------------+------+
# |     User       |  ID  |
# +----------------+------+
# | Owner          |   0  |
# | Second Space   |  10  |
# | App Clone      | 999  |
# +----------------+------+
# -----------------🌼🌼----------------------- #
# package_name ▼
# com.topjohnwu.magisk # Otherwise, assume the user ID is 0.
# 0:com.termux
# -----------------🌼🌼----------------------- #
# Gid ▼
# 12345
# 1000
init

# Extract mode, package list and gid list
# proxy_mode=$(busybox awk -F: '/^mode:/ {print $2}' ${pkg_config} | tr -d ' ')
# packages_list=($(busybox awk '!/^#/ && /^[^ ]*\.([^ ]*)/ {print $1}' ${pkg_config}))
# gid_list=($(busybox awk '!/^#/ && /^[0-9]{1,8}/ {print $1}' ${pkg_config}))

# Extract mode, package list and gid list
proxy_mode=$(sed -n 's/^mode:\([^ ]*\).*/\1/p' ${pkg_config})
packages_list=($(sed -n '/^[^#]/s/^\([^ ]*\.[^ ]*\).*/\1/p' ${pkg_config}))
# gid_list=($(sed -n '/^[^#]/s/^\([0-9]\{1,8\}\).*/\1/p' ${pkg_config}))
gid_list=($(busybox awk '!/^#/ && /^[0-9]+$/ {print $1}' ${pkg_config}))

# -----------------------------------------------------------------
# Network State Control
# -----------------------------------------------------------------

# Enable or disable controlling the module service based on network state
# false = "disabled by default" | true = "enabled"
enable_network_service_control=false

# Enable module service when Wi-Fi is disconnected
use_module_on_wifi_disconnect=true

# Enable module service when connected to Wi-Fi
use_module_on_wifi=false

# Enable Wi-Fi SSID matching (requires SSID list)
use_ssid_matching=false

# Wi-Fi SSID matching mode
# blacklist = deny listed SSIDs | whitelist = allow only listed SSIDs
use_wifi_list_mode="blacklist"

# Wi-Fi SSID list to match (multiple SSIDs separated by spaces or commas)
wifi_ssids_list="WiFi1 WiFi2"

# Enable inotify debug logging for network switching
inotify_log_enabled="true"

notify() {
  true

  # eg: notify $title $content
  # using Xposed edge app toast
  # am start -a android.intent.action.VIEW -n com.jozein.xedgepro/.ui.ActivityPerformAction --ei __0 111 --es __1 "$2" >/dev/null 2>&1

  # using system notification
  # su -lp "2000" -c "cmd notification post -S messaging --conversation '$1' --message '$1':'$2' 'Tag' '$(echo $RANDOM)' " >/dev/null 2>&1
}

log() {
  normal="\033[0m"
  orange="\033[1;38;5;208m"
  red="\033[1;31m"
  green="\033[1;32m"
  yellow="\033[1;33m"
  blue="\033[1;34m"
  # Selects the text color according to the parameters
  case $1 in
    Info) color="${blue}" ;;
    Error) color="${red}" ;;
    Warning) color="${yellow}" ;;
    *) color="${green}" ;;
  esac
  # Add messages to time and parameters
  message="${current_time} [$1]: $2"
  if [ -t 1 ]; then
    # Prints messages to the console
    echo -e "${color}${message}${normal}"
  else
    # Print messages to a log file
    echo "${message}" | tee -a "${box_log}"
  fi
  
  if [[ $TOAST ]]; then
      notify "box_for_root" "${message}"
  fi
}
